home *** CD-ROM | disk | FTP | other *** search
/ BBS Toolkit / BBS Toolkit.iso / doors_1 / doorskl3.zip / XBBSMSG.ZIP / GETABNCH.C next >
C/C++ Source or Header  |  1991-12-14  |  9KB  |  392 lines

  1. /*
  2.  *  Does 'threading', finds personal msgs, etc. very fast
  3.  *  This is a "genericized" version of what HeadEdit uses
  4.  *  There are a few functions in here available in other source
  5.  *  I've released, such as rstrip, lstrip, stristr, etc.
  6.  *  I'm including these at the bottom of this in case you
  7.  *  don't already have them.
  8.  */
  9.  
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <fcntl.h>
  13. #include <io.h>
  14. #include <share.h>
  15. #include <errno.h>
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20. #include "xmsg.h"
  21.  
  22. #ifdef DONTHAVE
  23.  char * _fastcall rstrip (char *a);
  24.  char * _fastcall lstrip (char *a);
  25.  char * _fastcall stripcr (char *a);
  26.  char * _fastcall stristr (char *t, char *s);
  27. #endif
  28.  
  29. unsigned int _fastcall thread (int mode,USHORT cp,int which,
  30.                                unsigned int messno,char *body,
  31.                                XMSG *msg,MSGAREA *info);
  32. unsigned int _fastcall get_abunch (int mode,USHORT cp,MSGAREA *info,
  33.                                    unsigned int messno,char type,
  34.                                    int direction,char *str,char *uname);
  35.  
  36.  
  37.     #define BUFMSGS 12
  38.  
  39.  
  40. unsigned int _fastcall get_abunch (int mode,USHORT cp,MSGAREA *info,
  41.                                    unsigned int messno,char type,
  42.                                    int direction,char *str,char *uname) {
  43.  
  44.  /*
  45.   * messno =     message # to start at (usually current # or lmr setting)
  46.   *
  47.   * type   =     0...personal message check (something to you that you
  48.   *                  haven't read yet)
  49.   *              1...subject check.  find a matching subject.  used for
  50.   *                  threading messages that have no MSGID/REPLY kludge.
  51.   *              2...body check.  find a match in the msg body in the first
  52.   *                  512 bytes (used for MSGID/REPLY).
  53.   *
  54.   * direction == -1 (reverse) or 1 (forward)
  55.   *
  56.   * str       == string to match if type == 1 or type == 2
  57.   *
  58.   * returns 0 (no match) or msg # of match.
  59.   */
  60.  
  61.  XMSG          msgs[BUFMSGS];
  62.  int           handle,handle2,temp2,y;
  63.  char          finished = 0,once,*p;
  64.  unsigned int  temp,x = 0;
  65.  
  66.  
  67.  if(type && !str) return 0;
  68.  
  69.  if(direction >= 0) {
  70.     messno++;
  71.     direction = 1;
  72.  }
  73.  else direction = -1;
  74.  
  75.  {
  76.     char filename[24];
  77.  
  78.     sprintf(filename,"./MSG/XDATA.%03x",info->number);
  79.     while ((handle = sopen(filename,O_NOINHERIT | O_RDONLY | O_BINARY, SH_DENYNO)) == -1) {
  80.          if (errno == EACCES) {
  81.             x++;
  82.             if(x > 10) {
  83.                 return 0;
  84.             }
  85.             DosSleep(500L);
  86.          }
  87.          else  {
  88.             return 0;
  89.          }
  90.     }
  91.  }
  92.  
  93.  if(direction < 0) {
  94.     if(messno > BUFMSGS - 1) {
  95.         x = BUFMSGS;
  96.         messno -= BUFMSGS;
  97.     }
  98.     else {
  99.         x = messno - 1;
  100.         messno = 1;
  101.     }
  102.  }
  103.  else {
  104.  }
  105.  
  106. Loop:
  107.  
  108.  DosSleep(1L);
  109.  memset(&msgs[0],0,sizeof(XMSG) * BUFMSGS);
  110.  
  111.  if(direction > 0) {
  112.     x = (unsigned int)(filelength(handle) / (long)sizeof(XMSG));
  113.     if(messno > x || finished) {
  114.         close(handle);
  115.         return 0;
  116.      }
  117.      if((x - messno) < BUFMSGS - 1) x -= (messno - 1);
  118.      else x = BUFMSGS;
  119.  }
  120.  
  121.  if ((lseek(handle,(long)((long)(messno - 1) * (long)sizeof(XMSG)),SEEK_SET) == -1) || ((temp = (read(handle,&msgs,(x * sizeof(XMSG))))) < 1)) {
  122.     close(handle);
  123.     return 0;
  124.  }
  125.  if((temp / sizeof(XMSG)) < x) x = temp / sizeof(XMSG);
  126.  if(direction < 0) y = x - 1;
  127.  else y = 0;
  128.  
  129.  if(type == 0) {  /* Personal mail check */
  130. #ifdef DEBUG
  131.     printf("\r\nx=%u  y=%u  dir=%d",x,y,direction);
  132. #endif
  133.     for(;;) {
  134.         if((msgs[y].xflags & MSGDELETED) || (msgs[y].fflags & MSGREAD)) goto NoGot;
  135.  
  136. #ifdef DEBUG
  137.     printf("\r\nx=%u  y=%u  dir=%d",x,y,direction);
  138. #endif
  139.  
  140.         rstrip(msgs[y].to);
  141.         if(*msgs[y].to) {
  142.  
  143.             /* this could be expanded to check for multiple names */
  144.  
  145.             if(!stricmp(msgs[y].to,uname)) goto GotIt;
  146.         }
  147.         else goto NoGot;
  148.  
  149. GotIt:
  150.  
  151.         close(handle);
  152.         return (messno + y);
  153.  
  154. NoGot:
  155.  
  156.         y += (direction);
  157.         if(direction < 0) {
  158.             if(y < 0) break;
  159.         }
  160.         else if(y >= (int)x) break;
  161.     }
  162.  }
  163.  else if (type == 1) { /* Subject check */
  164.     temp = strlen(str);
  165.     for(;;) {
  166.         if (msgs[y].xflags & MSGDELETED) goto NoGot2;
  167.         p = msgs[y].subj;
  168.         rstrip(p);
  169.         lstrip(p);
  170.         while(!strnicmp(p,"RE:",3)) {
  171.             p += 3;
  172.             while(*p == ' ') p++;
  173.         }
  174.         if(!*p) {
  175.             if(!*str) {
  176.                 close(handle);
  177.                 return (messno + y);
  178.             }
  179.             else {
  180.                 goto NoGot2;
  181.             }
  182.         }
  183.         handle2 = min(24,temp);
  184.         handle2 = min(handle2,(int)strlen(p));
  185.         if(!strnicmp(p,str,handle2) || (!*p && !*str)) {
  186.  
  187.             close(handle);
  188.             return (messno + y);
  189.         }
  190. NoGot2:
  191.         y += (direction);
  192.         if(direction<0) {
  193.             if(y < 0) break;
  194.         }
  195.         else if(y >= (int)x) break;
  196.     }
  197.  }
  198.  else if (type == 2) { /* Body check */
  199.  
  200.      if(!*str) {
  201.         close(handle);
  202.         return 0;
  203.      }
  204.  
  205.      {
  206.         char filename[24];
  207.  
  208.         sprintf(filename,"./MSG/XTEXT.%03x",info->number);
  209.         temp = 0;
  210.         while ((handle2 = sopen(filename,O_NOINHERIT | O_RDONLY | O_BINARY, SH_DENYNO)) == -1) {
  211.              if (errno == EACCES) {
  212.                 temp++;
  213.                 if (temp > 10) {
  214.                     close(handle);
  215.                     return 0;
  216.                 }
  217.                 DosSleep(500L);
  218.              }
  219.              else {
  220.                 close(handle);
  221.                 return 0;
  222.              }
  223.         }
  224.     }
  225.     for(;;) {
  226.      if(!msgs[y].length) goto NoGot3;
  227.      if ((msgs[y].xflags & MSGDELETED)) goto NoGot3;
  228.      once = 0;
  229.      while((lseek(handle2,msgs[y].start,SEEK_SET)) == -1L) {
  230.          if(once < 3) {
  231.              once++;
  232.          }
  233.          else {
  234.             goto NoGot3;
  235.          }
  236.      }
  237.  
  238.      {
  239.         char buffer[514];
  240.  
  241.         *buffer = 0;
  242.         temp2 = min(msgs[y].length - 1,512);
  243.         if(!DosRead(handle2,buffer,temp2,&temp)) {
  244.           buffer[temp + 1] = 0;
  245.               if(stristr(buffer,str)) {
  246.                close(handle);
  247.                close(handle2);
  248.                return (messno + y);
  249.             }
  250.         }
  251.      }
  252.  
  253. NoGot3:
  254.  
  255.      y += (direction);
  256.      if(direction < 0) {
  257.         if(y < 0) break;
  258.      }
  259.      else if(y >= (int)x) break;
  260.    }
  261.    close(handle2);
  262.  }
  263.  
  264.  if(direction > 0) {
  265.     if((long)messno + (long)x > 65535L) finished = 1;
  266.     else messno += x;
  267.  }
  268.  else {
  269.     if(messno == 1) {
  270.         close(handle);
  271.         return 0;
  272.     }
  273.     else {
  274.         if(messno <= x) messno = 1;
  275.         else messno -= x;
  276.     }
  277.  }
  278.  goto Loop;
  279. }
  280.  
  281.  
  282.  
  283. unsigned int _fastcall thread (int mode,USHORT cp,int which,
  284.                                unsigned int messno,char *body,
  285.                                XMSG *msg,MSGAREA *info) {
  286.  
  287.  /*
  288.   * performs threading forward or backward in an area.
  289.   * if which == 'B' threads backward, else threads forward.
  290.   * is smart enough to reverse at end/beginning of message.
  291.   * if body contains anything, it's used (MSGID/REPLY),
  292.   * else the msg->subj is matched.
  293.   * returns matching message # or 0 on no-match
  294.   */
  295.  
  296.  
  297.     unsigned int nomess;
  298.     int          direction;
  299.     XMSG         msg2;
  300.     char         *p;
  301.  
  302.  
  303.     nomess = how_many_msgs(info);
  304.     if (nomess <= 1) return 0;
  305.     if (messno >= nomess) which = 'B';
  306.     if (messno <= 1) which = 'F';
  307.     if (which != 'B' && which != 'F') which = 'F';
  308.     if(which == 'B')  direction = (-1);
  309.     else direction = 1;
  310.  
  311.     if(!body || !*body) {
  312.         p = msg->subj;
  313.         lstrip(p);
  314.         rstrip(p);
  315.         while(!strnicmp(p,"RE:",3)) {
  316.             p += 3;
  317.             while(*p == ' ') p++;
  318.         }
  319.         messno = get_abunch(mode,cp,info,messno,1,direction,p);
  320.     }
  321.     else {
  322.         messno = get_abunch(mode,cp,info,messno,2,direction,body);
  323.     }
  324.  
  325.     /* note:  you might want to check security on the message found... */
  326.  
  327.     return messno;
  328. }
  329.  
  330.  
  331.  
  332. #ifdef DONTHAVE
  333.  
  334. char * _fastcall rstrip (char *a) { /* strips trailing spaces */
  335.  
  336.   register int x;
  337.  
  338.  
  339.   x = strlen(a);
  340.   while (x && a && a[x - 1] == ' ') a[--x] = 0;
  341.   return a;
  342. }
  343.  
  344.  
  345.  
  346. char * _fastcall lstrip (char *a) { /* strips leading spaces */
  347.  
  348.   register int x;
  349.  
  350.  
  351.   x = strlen(a);
  352.   while (x && *a == ' ') memmove (a,(a + 1),x--);
  353.   return (a);
  354. }
  355.  
  356.  
  357. char * _fastcall stripcr (char *a) { /* strips trailing cr/lfs */
  358.  
  359.   register int x;
  360.  
  361.  
  362.   x = strlen(a);
  363.   while (x && (a[x - 1] == '\n' || a[x - 1] == '\r')) a[--x] = 0;
  364.   return a;
  365.  
  366. }
  367.  
  368. /* insensitive strstr()  */
  369.  
  370. char * _fastcall stristr (char *t, char *s) {
  371.  
  372.    char *t1;
  373.    char *s1;
  374.  
  375.    while(*t) {
  376.       t1 = t;
  377.       s1 = s;
  378.       while(*s1) {
  379.          if (toupper(*s1) != toupper(*t)) break;
  380.          else {
  381.             s1++;
  382.             t++;
  383.          }
  384.       }
  385.       if (!*s1) return t1;
  386.       t = t1 + 1;
  387.    }
  388.    return NULL;
  389. }
  390.  
  391. #endif
  392.